package com.aries.ui.view;


import com.aries.ui.view.viewgroup.ViewGroup;
import com.aries.ui.impl.ViewGroupImpl;
import ohos.agp.components.*;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;


/**
 * @Author: AriesHoo on 2018/7/19 10:31
 * @E-Mail: AriesHoo@126.com
 * Function: 通过ViewDragHelper实现拖拽效果
 * Description:
 */
public class DragLayout extends StackLayout implements Component.TouchEventListener, ViewGroup, ComponentTreeObserver.ScrollChangedListener {

    private static final int INVALID_POINTER = -1;
    //    private final float mDensity;
    boolean mDragEnable = true;
    private OnDragListener mListener;
    private int mHeight;
    private int mTop;
    private int mActivePointerId;
    private boolean mIsBeingDragged;
    private float mInitialMotionY;
    private boolean mCollapsible = false;
    private float yDiff;
    private ViewGroupImpl impl;


    private int mLastY;




    private void init() {

        impl = new ViewGroupImpl(this);
        setTouchEventListener(this);
        getComponentTreeObserver().addScrolledListener(this);

//        setDraggedListener(DRAG_HORIZONTAL_VERTICAL,this);

    }


    private void recover(int dis) {
//        if (mRefreshListener != null && dis > mHeadOverComponent.mPullRefreshHeight) {
//            /*
//             * 由于下拉的距离超过了下拉刷新的最小距离，所以需先要向上滚动一段距离，
//             * 也就是需要滚动到mHiOverView.mPullRefreshHeight这个距离，然后才开始刷新，
//             * 需要向上滚动多少距离才能到达mHiOverView.mPullRefreshHeight这个距离呢？
//             * dis - mHiOverView.mPullRefreshHeight就是需要向上滚动的距离
//             */
//            mAutoScroll.recover(dis - mHeadOverComponent.mPullRefreshHeight);
//            mState = HeadOverComponent.RefreshState.STATE_OVER_RELEASE;
//        } else {
//            // 没有达到下拉刷新的最小距离，也就是没有达到mHiOverView.mPullRefreshHeight这个距离，
//            // 此时就应当直接向上滚动，也就是隐藏头部视图
//            mAutoScroll.recover(dis);
//        }


    }

    public DragLayout(Context context) {
        this(context, null);
        init();
    }

    public DragLayout(Context context, AttrSet attrs) {
        this(context, attrs, "");
        init();
    }

    //    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public DragLayout(Context context, AttrSet attrs, String styleName) {
        super(context, attrs, styleName);
//        mDragHelper = ViewDragHelper.create(this, 0.8f, new ViewDragCallback());
//        mDensity = getResources().getDisplayMetrics().density * 400;
    }

    @Override
    public boolean onInterceptTouchEvent(TouchEvent event) {
//        final int action = TouchEvent.getActionMasked(event);
        final int action = event.getAction();

        if (!isEnabled()) {
            // Fail fast if we're not in a state where a swipe is possible
            return false;
        }

        if (action == TouchEvent.PHASE_CANCEL || action == TouchEvent.PRIMARY_POINT_UP) {
            mActivePointerId = INVALID_POINTER;
            mIsBeingDragged = false;
//            if (mCollapsible && -yDiff > mDragHelper.getTouchSlop()) {
//                expand(mDragHelper.getCapturedView(), 0);
//            }
//            mDragHelper.cancel();
            return false;
        }

        switch (action) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                mHeight = getComponentAt(0).getHeight();
                mTop = getComponentAt(0).getTop();
//                mActivePointerId = MotionEventCompat.getPointerId(event, 0);
                mIsBeingDragged = false;
                final float initialMotionY = getMotionEventY(event, mActivePointerId);
                if (initialMotionY == -1) {
                    return false;
                }
                mInitialMotionY = initialMotionY;
                yDiff = 0;
                break;
            case TouchEvent.PHASE_MOVE:
                if (mActivePointerId == INVALID_POINTER) {
                    return false;
                }
                final float y = getMotionEventY(event, mActivePointerId);
                if (y == -1) {
                    return false;
                }
                yDiff = (float) ((double)y - (double)mInitialMotionY);
//                if (mDragEnable && yDiff > mDragHelper.getTouchSlop() && !mIsBeingDragged) {
//                    mIsBeingDragged = true;
//                    mDragHelper.captureChildView(getComponentAt(0), 0);
//                }
                break;
        }
//        mDragHelper.shouldInterceptTouchEvent(event);

        return mIsBeingDragged;
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean b) {
        // Nope.
    }

    private float getMotionEventY(TouchEvent ev, int activePointerId) {
//        final int index = MotionEventCompat.findPointerIndex(ev, activePointerId);
//        if (index < 0) {
//            return -1;
//        }
//        return MotionEventCompat.getY(ev, index);
        return -1;
    }

    @Override
    public boolean dispatchTouchEvent(TouchEvent event) {
        return false;
    }

    @Override
    public boolean onTouchEvent(TouchEvent ev) {
        if (!isEnabled()) {
            return false;
        }
        try {
            if (mDragEnable) {
//                mDragHelper.processTouchEvent(ev);
            }
        } catch (Exception ignored) {
        }
        return true;
    }

    @Override
    public boolean isConsumed() {
        return false;
    }

//    @Override
//    public void computeScroll() {
//        if (mDragHelper.continueSettling(true)) {
//            ViewCompat.postInvalidateOnAnimation(this);
//        }
//    }

    @Override
    public void onScrolled() {
//        if (mDragHelper.continueSettling(true)) {
//            ViewCompat.postInvalidateOnAnimation(this);
//        }
    }

    public DragLayout setOnDragListener(OnDragListener listener) {
        mListener = listener;
        return this;
    }

    public DragLayout setCollapsible(boolean mCollapsible) {
        this.mCollapsible = mCollapsible;
        return this;
    }

    public DragLayout setDragEnable(boolean enable) {
        this.mDragEnable = enable;
        return this;
    }

    private void expand(Component releasedChild, float yvel) {
        if (mListener != null) {
            mListener.onOpened();
        }
    }

    private void dismiss(Component view, float yvel) {
//        mDragHelper.smoothSlideViewTo(view, 0, mTop + getHeight());
//        ViewCompat.postInvalidateOnAnimation(DragLayout.this);
    }

    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        return false;
    }


    /**
     * set listener
     */
    public interface OnDragListener {

        /**
         * Drag关闭回调
         */
        void onClosed();

        /**
         * Drag开启回调
         */
        void onOpened();
    }

//    /**
//     * Callback
//     */
//    private class ViewDragCallback extends ViewDragHelper.Callback {
//
//
//        @Override
//        public boolean tryCaptureView(View child, int pointerId) {
//            return true;
//        }
//
//        @Override
//        public void onViewReleased(View releasedChild, float xvel, float yvel) {
//            if (yvel > mDensity) {
//                dismiss(releasedChild, yvel);
//            } else {
//                if (releasedChild.getTop() >= mTop + mHeight / 2) {
//                    dismiss(releasedChild, yvel);
//                } else {
//                    mDragHelper.smoothSlideViewTo(releasedChild, 0, mTop);
//                    ViewCompat.postInvalidateOnAnimation(DragLayout.this);
//                }
//            }
//        }
//
//        @Override
//        public void onViewPositionChanged(View changedView, int left, int mTop, int dx, int dy) {
//            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
//                invalidate();
//            }
//            if (mHeight - mTop < 1 && mListener != null) {
//                mDragHelper.cancel();
//                mListener.onClosed();
//                mDragHelper.smoothSlideViewTo(changedView, 0, mTop);
//            }
//        }
//
//        @Override
//        public int clampViewPositionVertical(View child, int mTop, int dy) {
//            return Math.max(mTop, DragLayout.this.mTop);
//        }
//    }


//    @Override
//    public void onDragDown(Component component, DragInfo dragInfo) {
//
//    }
//
//    @Override
//    public void onDragStart(Component component, DragInfo dragInfo) {
//
//    }
//
//    @Override
//    public void onDragUpdate(Component component, DragInfo dragInfo) {
//        invalidate();
//        if (mHeight - mTop < 1 && mListener != null) {
//            mDragHelper.cancel();
//            mListener.onClosed();
//            mDragHelper.smoothSlideViewTo(component, 0, mTop);
//        }
//    }
//
//    @Override
//    public void onDragEnd(Component component, DragInfo dragInfo) {
//       float yvel  = (float) dragInfo.xVelocity;
//        if (yvel > mDensity) {
//            dismiss(component, yvel);
//        } else {
//            if (component.getTop() >= mTop + mHeight / 2) {
//                dismiss(component, yvel);
//            } else {
//                mDragHelper.smoothSlideViewTo(component, 0, mTop);
//                ViewCompat.postInvalidateOnAnimation(DragLayout.this);
//            }
//        }
//    }
//
//    @Override
//    public void onDragCancel(Component component, DragInfo dragInfo) {
//
//    }

}